package com.example.graduate.service.Impl;

import com.alibaba.fastjson.JSONObject;
import com.example.graduate.conf.Exception.OrderException;
import com.example.graduate.conf.webSocket.WebSocketServer;
import com.example.graduate.dto.*;
import com.example.graduate.env.OrderStatusEnum;
import com.example.graduate.env.ResponseCodeEnum;
import com.example.graduate.env.TaskStatusEnum;
import com.example.graduate.mapper.OrderMapper;
import com.example.graduate.mapper.RepaySerialMapper;
import com.example.graduate.mapper.TaskMapper;
import com.example.graduate.mapper.UserMapper;
import com.example.graduate.pojo.*;
import com.example.graduate.response.DataResponse;
import com.example.graduate.service.OrderService;
import com.example.graduate.util.MessageUtils;
import com.example.graduate.util.RedisUtil;
import com.example.graduate.util.UuidUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static com.example.graduate.env.RedisKeyConstants.CANCEL_ORDER_USER;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    UuidUtils uuidUtils;

    @Resource
    TaskMapper taskMapper;

    @Resource
    UserMapper userMapper;

    @Resource
    RepaySerialMapper repaySerialMapper;

    @Autowired
    RedisUtil redisUtil;

    @Override
    public DataResponse getInfo(GetDataRequest request) {
        List<ShopOrder> order = orderMapper.getOrder(request);
        log.info("【获取主页面数据】订单消息:{}", JSONObject.toJSONString(order));
        return new DataResponse(order, uuidUtils.getToken(UuidUtils.userId), ResponseCodeEnum.success.getCode());
    }

    @Override
    public DataResponse acceptOrder(AcceptOrderRequest acceptOrderRequest) {
        Order order = orderMapper.getOrderById(acceptOrderRequest.getOrderId());
        if (Objects.isNull(order)) {
            log.info("【确认接单】数据库数据异常");
            return new DataResponse(ResponseCodeEnum.SYSTEM_ERROR.getCode());
        }
        if (OrderStatusEnum.RUNNING.getCode().equals(order.getOrderStatus())) {
            log.info("【确认接单】订单已经在进行中");
            return new DataResponse(ResponseCodeEnum.REPEAT_REQUEST.getCode());
        }
        if (orderMapper.updateOrder(acceptOrderRequest.getOrderId(), acceptOrderRequest.getUserId(), OrderStatusEnum.RUNNING.getCode()) > 0) {
            log.info("【确认接单】接单成功");
            // 添加还款流水
            RepaySerial repaySerial = new RepaySerial(acceptOrderRequest);
            repaySerialMapper.insertRepaySerial(repaySerial);

            //发送信息
            Order temp = orderMapper.getOrderById(acceptOrderRequest.getOrderId());
            WebSocketServer.sendMessage(MessageUtils.getMessage("1",MessageUtils.message2), Long.parseLong(acceptOrderRequest.getUserId()));
            WebSocketServer.sendMessage(MessageUtils.getMessage("1",MessageUtils.message1), temp.getUserId());

            return new DataResponse(uuidUtils.getToken(UuidUtils.userId), ResponseCodeEnum.success.getCode());
        }
        log.info("【确认接单】系统异常");
        return new DataResponse(ResponseCodeEnum.SYSTEM_ERROR.getCode());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DataResponse cancelOrder(CancelOrderRequest cancelOrderRequest) {
        if (!redisUtil.setIfAbsent(CANCEL_ORDER_USER + ":" + cancelOrderRequest.getOrderId(), cancelOrderRequest.getUserId())) {
            log.info("【取消订单】订单{},存在正在取消的订单", cancelOrderRequest.getOrderId());
            return new DataResponse(ResponseCodeEnum.ORDER_CANCELING.getCode());
        }
        try {
            if (orderMapper.updateOrder(cancelOrderRequest.getOrderId(), cancelOrderRequest.getUserId(), OrderStatusEnum.CANCEL.getCode()) > 0) {
                RepaySerial serial = new RepaySerial(cancelOrderRequest);
                repaySerialMapper.insertRepaySerial(serial);
                log.info("【取消订单】订单{},已成功取消", cancelOrderRequest.getOrderId());
                redisUtil.delete(CANCEL_ORDER_USER + ":" + cancelOrderRequest.getOrderId());

                //发送信息
                WebSocketServer.sendMessage(MessageUtils.getMessage("1",MessageUtils.message3), Long.parseLong(cancelOrderRequest.getUserId()));

                return new DataResponse(uuidUtils.getToken(UuidUtils.userId), ResponseCodeEnum.success.getCode());
            } else {
                log.info("【取消订单】订单{},该订单已被取消{}:", cancelOrderRequest.getOrderId());
                return new DataResponse(ResponseCodeEnum.ORDER_CANCELED.getCode());
            }
        } catch (Exception e) {
            log.error("【取消订单】系统异常{}:", e);
            throw new OrderException(ResponseCodeEnum.CHECK_SYSTEM.getCode());
        }
    }

    @Override
    public DataResponse completeOrder(CompleteOrderRequest completeOrder) {
        try {
            orderMapper.updateOrder(completeOrder.getOrderId(), completeOrder.getUserId(), OrderStatusEnum.OVER.getCode());
            RepaySerial serial = new RepaySerial(completeOrder);
            repaySerialMapper.insertRepaySerial(serial);

            //发送信息
            Order order = orderMapper.getOrderById(completeOrder.getOrderId());
            WebSocketServer.sendMessage(MessageUtils.getMessage("1",MessageUtils.message4), Long.parseLong(completeOrder.getUserId()));
            WebSocketServer.sendMessage(MessageUtils.getMessage("1",MessageUtils.message4), order.getAdvisersId());

            log.info("【订单完成】订单{}", completeOrder.getOrderId());
            return new DataResponse(uuidUtils.getToken(UuidUtils.userId), ResponseCodeEnum.success.getCode());
        } catch (Exception e) {
            log.error("【订单完成】系统异常{}:", e);
            throw new OrderException(ResponseCodeEnum.CHECK_SYSTEM.getCode());
        }
    }

    @Override
    public DataResponse getAcceptOrder(GetAcceptOrderRequest getAcceptOrderRequest) {
        List<ShopOrder> list = null;
        try {
            list = orderMapper.selectOrderByAdvisersId(getAcceptOrderRequest.getUserId(), OrderStatusEnum.RUNNING.getCode());
        } catch (Exception e) {
            log.error("【获取用户正在接单数据】,数据库连接异常");
            return new DataResponse(ResponseCodeEnum.SYSTEM_ERROR.getCode());
        }
        return new DataResponse(list, uuidUtils.getToken(UuidUtils.userId), ResponseCodeEnum.success.getCode());
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public DataResponse addOrder(AddOrderRequest addOrderRequest) {
        try {
            User user = userMapper.getUserById(addOrderRequest.getUserId());
            if (BigDecimal.valueOf(user.getBalance()).compareTo(addOrderRequest.getAward()) < 0) {
                return new DataResponse(ResponseCodeEnum.NOT_ENOUGH_MONEY.getCode());
            }
            userMapper.updateBalanceToReapymentDoing(addOrderRequest.getUserId(), addOrderRequest.getAward().doubleValue());

            // 添加任务
            Task task = new Task(addOrderRequest);
            taskMapper.insertTask(task);

            // 添加订单
            Order order = new Order(addOrderRequest, task.getId());
            orderMapper.insertOrder(order);

            //更新任务表ID
            taskMapper.updateTaskOrderId(order.getId(), task.getId());

            // 添加还款流水
            RepaySerial repaySerial = new RepaySerial(addOrderRequest, order.getId());
            repaySerialMapper.insertRepaySerial(repaySerial);

            //发送信息
            WebSocketServer.sendMessage(MessageUtils.getMessage(addOrderRequest.getOrderType(),MessageUtils.message), addOrderRequest.getUserId());
        } catch (Exception e) {
            log.error("【发单接口】异常:{}", e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new OrderException(ResponseCodeEnum.SYSTEM_ERROR.getCode());
        }
        return new DataResponse(uuidUtils.getToken(UuidUtils.userId), ResponseCodeEnum.success.getCode());
    }

    @Override
    public DataResponse getHistoryOrder(GetHistoryOrderRequest getHistoryOrderRequest) {
        List<ShopOrder> orders = orderMapper.selectHistoryOrder(getHistoryOrderRequest.getUserId(), getHistoryOrderRequest.getOrderType());
        log.info("【获取用户历史订单数据】数据为:{}", JSONObject.toJSONString(orders));
        return new DataResponse(orders, uuidUtils.getToken(UuidUtils.userId), ResponseCodeEnum.success.getCode());
    }

    @Override
    public DataResponse getHistoryAcceptOrder(GetHistoryOrderRequest getHistoryOrderRequest) {
        List<ShopOrder> orders = orderMapper.selectHistoryAcceptOrder(getHistoryOrderRequest.getUserId());
        log.info("【获取用户历史订单数据】数据为:{}", JSONObject.toJSONString(orders));
        return new DataResponse(orders, uuidUtils.getToken(UuidUtils.userId), ResponseCodeEnum.success.getCode());
    }

    @Override
    public DataResponse getPushOrder(GetPushOrderRequest getPushOrderRequest) {
        List<ShopOrder> list = null;
        List<String> objects = new ArrayList<>();
        objects.add(OrderStatusEnum.RUNNABLE.getCode());
        objects.add(OrderStatusEnum.RUNNING.getCode());
        try {
            list = orderMapper.selectOrderByUserIdAndOrderTypeAndOrderStatus(getPushOrderRequest.getUserId(), getPushOrderRequest.getOrderType(), objects);
        } catch (Exception e) {
            log.error("【获取用户正在接单数据】,数据库连接异常:{}", JSONObject.toJSONString(e.getMessage()));
            return new DataResponse(ResponseCodeEnum.SYSTEM_ERROR.getCode());
        }
        return new DataResponse(list, uuidUtils.getToken(UuidUtils.userId), ResponseCodeEnum.success.getCode());
    }
}
